#pragma once

#include<iostream>
#include <jsoncpp/json/json.h>
#include<string>

namespace protocal
{
 
const std::string sep="\n\r";

std::string Encode(std::string& json_str)
{
    std::string ret=std::to_string(2*sep.size()+json_str.size());
    ret+=sep;
    ret+=json_str;
    ret+=sep;

    return ret;
}

std::string Decode(std::string& inbuf)
{
    size_t pos=inbuf.find(sep);
    if(std::string::npos==pos)
    {
        return std::string();
    }
    int len=std::stoi(inbuf.substr(0,pos));
    if(pos+len<inbuf.size())
    {
        return std::string();
    }
    std::string json_str=inbuf.substr(pos+sep.size(),len-2*sep.size());
    inbuf.erase(0,pos+len);

    return json_str;
}

class Request
{
public:
    Request(float x,float y,char opera)
    :_x(x),
    _y(y),
    _opera(opera)
    {}

    Request()
    {}

    void SerializeRequest(std::string& json_str)
    {
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["opera"]=_opera;

        json_str = root.toStyledString();
    }

    void DeserializeRequest(std::string& json_str)
    {
        Json::Reader reader;
        Json::Value root;
        if(reader.parse(json_str,root))
        {
            _x=root["x"].asFloat();
            _y=root["y"].asFloat();
            _opera=root["opera"].asInt();
        }
    }

    ~Request()
    {}
public:
    float _x;
    float _y;
    char _opera;
};

class Response
{
public:
    Response(float result,char stat)
    :_result(result),
    _stat(stat)
    {}

    Response()
    {}

    ~Response()
    {}

    void DeserializeResponse(std::string& json_str)
    {
        Json::Reader reader;
        Json::Value root;
        if(reader.parse(json_str,root))
        {
            _result=root["result"].asFloat();
            _stat=root["stat"].asInt();
        }
    }

    void SerializeResponse(std::string& json_str)
    {
        Json::Value root;
        root["result"]=_result;
        root["stat"]=_stat;

        json_str=root.toStyledString();
    }

public:
    float _result;
    char _stat;
};

}
